<?php
/**
 * A simple description for this script
 *
 * PHP Version 5.2.0 or Upper version
 *
 * @package    Iris
 * @author     Hidehito NOZAWA aka Suin <http://suin.asia>
 * @copyright  2010 Hidehito NOZAWA
 * @license    http://www.gnu.org/licenses/gpl-2.0.html GNU GPL v2
 *
 */

$path    = dirname(dirname(__FILE__));
$dirname = basename($path);

require_once $path.'/iris.php';

Iris::setup();

eval('
function xoops_module_install_'.$dirname.'($module)
{
	return Iris_Class_Installer::main($module, "'.$dirname.'", "install");
}
function xoops_module_update_'.$dirname.'($module)
{
	return Iris_Class_Installer::main($module, "'.$dirname.'", "update");
}
function xoops_module_uninstall_'.$dirname.'($module)
{
	return Iris_Class_Installer::main($module, "'.$dirname.'", "uninstall");
}
');

class Iris_Class_Installer
{
	protected static $ret = array();
	protected static $messages = array();
	protected static $module = null;
	protected static $dirname = null;
	protected static $event = null;

	protected static $moduleRootPath = null;

	public static function main($module, $dirname, $event)
	{
		self::$module  = $module;
		self::$dirname = $dirname;
		self::$event   = $event;
		self::$moduleRootPath = dirname(dirname(__FILE__));

		Iris::$dirname = $dirname; // TODO >> fix

		try
		{
			if ( self::$event == 'install' )
			{
				self::_install();
			}
			elseif ( self::$event == 'update' )
			{
				self::_update();
			}
			elseif ( self::$event == 'uninstall' )
			{
				self::_uninstall();
			}
		}
		catch(Exception $e)
		{
			self::_message();
			return false;
		}

		self::_message();
		return true;
	}

	protected static function _install()
	{
		self::_template();
		self::_addTable();
		self::_createPreference();
	}

	protected static function _update()
	{
		self::_template();
		self::_createPreference();
		self::_deleteLanguageCache();
	}

	protected static function _uninstall()
	{
		self::_dropTable();
		self::_deleteLanguageCache();
	}

	protected static function _message()
	{
		if ( defined('XOOPS_CUBE_LEGACY') )
		{
			$root =& XCube_Root::getSingleton();
			$root->mDelegateManager->add('Legacy.Admin.Event.ModuleInstall.'.ucfirst(self::$dirname).'.Success' , array(__CLASS__, 'messageAppend'));
			$root->mDelegateManager->add('Legacy.Admin.Event.ModuleInstall.'.ucfirst(self::$dirname).'.Fail' , array(__CLASS__, 'messageAppend'));
			$root->mDelegateManager->add('Legacy.Admin.Event.ModuleUpdate.'.ucfirst(self::$dirname).'.Success' , array(__CLASS__, 'messageAppend'));
			$root->mDelegateManager->add('Legacy.Admin.Event.ModuleUpdate.'.ucfirst(self::$dirname).'.Fail' , array(__CLASS__, 'messageAppend'));
			$root->mDelegateManager->add('Legacy.Admin.Event.ModuleUninstall.'.ucfirst(self::$dirname).'.Success' , array(__CLASS__, 'messageAppend'));
			$root->mDelegateManager->add('Legacy.Admin.Event.ModuleUninstall.'.ucfirst(self::$dirname).'.Fail' , array(__CLASS__, 'messageAppend'));
		}
		else // XOOPS 2.x
		{
			if ( self::$event == 'update' )
			{
				global $msgs;
				$ret =& $msgs;
			}
			else
			{
				global $ret;
				$ret =& $ret;
			}

			if ( !is_array($ret) )
			{
				$ret = array();
			}

			foreach ( self::$messages as $message )
			{
				if ( $message['type'] == 'error' )
				{
					$ret[] = '<span style="color:#ff0000;">'.$message['connect'].'</span><br />';
				}
				else
				{
					$ret[] = $message['content'].'<br />';
				}
			}
		}
	}

	protected static function _addMessage($msg)
	{
		self::$messages[] = array('type' => 'message', 'content' => $msg);
	}

	protected static function _addError($msg)
	{
		self::$messages[] = array('type' => 'error', 'content' => $msg);
	}

	protected static function _template()
	{
		require_once XOOPS_ROOT_PATH.'/class/xoopsblock.php' ;
		require_once XOOPS_ROOT_PATH.'/class/template.php' ;

		$mid = self::$module->getVar('mid');

		$tplfileHandler =& xoops_gethandler('tplfile');
		$tplPath = self::$moduleRootPath.'/templates';

		$prefixMod = self::$dirname.'.';

		if ( $handler = @opendir($tplPath.'/') )
		{
			while ( ( $file = readdir($handler) ) !== false )
			{
				if ( substr($file, 0, 1) == '.' ) continue;

				$filePath = $tplPath.'/'.$file;

				if ( is_file($filePath) and substr($file, -4) == '.tpl' )
				{
					$mtime = intval(@filemtime($filePath));
					$tplfile =& $tplfileHandler->create();
					$tplfile->setVar('tpl_source', file_get_contents($filePath), true);
					$tplfile->setVar('tpl_refid', $mid);
					$tplfile->setVar('tpl_tplset', 'default');
					$tplfile->setVar('tpl_file', $prefixMod.$file);
					$tplfile->setVar('tpl_desc', '', true);
					$tplfile->setVar('tpl_module', self::$dirname);
					$tplfile->setVar('tpl_lastmodified', $mtime);
					$tplfile->setVar('tpl_lastimported', 0);
					$tplfile->setVar('tpl_type', 'module');

					if ( !$tplfileHandler->insert($tplfile) )
					{
						self::_addError('ERROR: Could not insert template <b>'.htmlspecialchars($prefixMod.$file).'</b> to the database.');
					}
					else
					{
						$tplid = $tplfile->getVar('tpl_id');
						self::_addMessage('Template <b>'.htmlspecialchars($prefixMod.$file).'</b> added to the database. (ID: <b>'.$tplid.'</b>)');
					}
				}
			}
			closedir($handler);
		}

		xoops_template_clear_module_cache($mid);
	}

	protected static function _createPreference()
	{
		$configFile = IRIS_PATH.DS.'config'.DS.'preference.php';

		if ( !file_exists($configFile) ) return;

		require $configFile;

		if ( !isset($configs) or !is_array($configs) or !count($configs) ) return;

		self::_addMessage('Preference file found at <b>'.htmlspecialchars($configFile).'</b>.<br /> Setting up preferences...');

		$configHandler = new Iris_Model_ConfigHandler;

		$configNames = array();

		foreach ( $configs as $config )
		{
			if ( !strlen($config['name']) ) continue;

			$configNames[] = $config['name'];

			$configModel = $configHandler->loadByName($config['name']);

			if ( !$configModel->isNew() ) continue;

			$configModel->setVar('name', $config['name']);
			$configModel->setVar('value', $config['default']);

			if ( $configHandler->save($configModel) )
			{
				self::_addMessage('Preference <b>'.htmlspecialchars($config['name']).'</b> created.');
			}
			else
			{
				self::_addError('Failed to create preference <b>'.htmlspecialchars($config['name']).'</b>.');
			}
		}

		$criteria = new Iris_Class_Criteria();
		$criteria->add('name', 'NOT IN', $configNames);

		$configModels = $configHandler->find($criteria);

		foreach ( $configModels as $configModel )
		{
			$id = $configModel->getVar('id');

			if ( $configHandler->delete($id) )
			{
				self::_addMessage('Preference <b>'.htmlspecialchars($configModel->getVar('name')).'</b> deleted.');
			}
			else
			{
				self::_addError('Failed to remove preference <b>'.htmlspecialchars($configModel->getVar('name')).'</b>.');
			}
		}

		$errors = $configHandler->getErrors();

		if ( count($errors) > 0 )
		{
			foreach ( $errors as $error )
			{
				self::_addError('Database Error: <b>'.htmlspecialchars($error).'</b>.');
			}
		}
	}

	protected static function _addTable()
	{
		$db =& Database::getInstance();
		$mid = self::$module->getVar('mid');

		$sqlFilePath = self::$moduleRootPath.'/sql/mysql.sql';
		$prefixMod = $db->prefix().'_'.self::$dirname;

		if ( !file_exists($sqlFilePath) )
		{
			return;
		}

		self::_addMessage('SQL file found at <b>'.htmlspecialchars($sqlFilePath).'</b>.<br /> Creating tables...');

		if ( file_exists(XOOPS_ROOT_PATH.'/class/database/oldsqlutility.php') )
		{
			include_once XOOPS_ROOT_PATH.'/class/database/oldsqlutility.php';
			$sqlutil =& new OldSqlUtility;
		}
		else
		{
			include_once XOOPS_ROOT_PATH.'/class/database/sqlutility.php';
			$sqlutil =& new SqlUtility;
		}

		$sqlQuery = trim(file_get_contents($sqlFilePath));

		$sqlutil->splitMySqlFile($pieces, $sqlQuery);

		$createdTables = array() ;

		if ( !is_array($pieces) )
		{
			return;
		}

		foreach ( $pieces as $piece )
		{
			$prefixedQuery = $sqlutil->prefixQuery($piece, $prefixMod);

			if ( !$prefixedQuery )
			{
				self::_addError('Invalid SQL <b>'.htmlspecialchars($piece).'</b>');
				throw new Exception("Invalid SQL");
			}

			if ( !$db->query($prefixedQuery[0]) )
			{
				self::_addError('<b>'.htmlspecialchars($db->error()).'</b>');

				throw new Exception("SQL Error");
			}
			else
			{
				if( !in_array($prefixedQuery[4], $createdTables) )
				{
					self::_addMessage('Table <b>'.htmlspecialchars($prefixMod.'_'.$prefixedQuery[4]).'</b> created.');
					$createdTables[] = $prefixedQuery[4];
				}
				else
				{
					self::_addMessage('Data inserted to table <b>'.htmlspecialchars($prefixMod.'_'.$prefixedQuery[4]).'</b>.');
				}
			}
		}
	}

	protected static function _dropTable()
	{
		$db =& Database::getInstance() ;
		$mid = self::$module->getVar('mid') ;

		$sqlFilePath = self::$moduleRootPath.'/sql/mysql.sql' ;
		$prefixMod = $db->prefix().'_'.self::$dirname;

		if ( !file_exists($sqlFilePath) )
		{
			return;
		}

		self::_addMessage('SQL file found at <b>'.htmlspecialchars($sqlFilePath).'</b>.<br  /> Deleting tables...');

		$sqlLines = file($sqlFilePath);

		foreach ( $sqlLines as $sqlLine )
		{
			if ( preg_match('/^CREATE TABLE \`?([a-zA-Z0-9_-]+)\`? /i', $sqlLine, $regs) )
			{
				$sql = 'DROP TABLE '.$prefixMod.'_'.$regs[1];

				if ( !$db->query($sql) )
				{
					self::_addError('ERROR: Could not drop table <b>'.htmlspecialchars($prefixMod.'_'.$regs[1]).'<b>.');
				}
				else
				{
					self::_addMessage('Table <b>'.htmlspecialchars($prefixMod.'_'.$regs[1]).'</b> dropped.');
				}
			}
		}
	}

	protected static function _deleteLanguageCache()
	{
		$cachePath = XOOPS_ROOT_PATH.DS.'cache';

		if ( defined('XOOPS_TRUST_PATH') )
		{
			if ( file_exists(XOOPS_TRUST_PATH.DS.'cache') )
			{
				$cachePath = XOOPS_TRUST_PATH.DS.'cache';
			}
		}

		$pattan = $cachePath.DS.self::$dirname.'_*';
		$files  = glob($pattan);

		foreach ( $files as $file )
		{
			if ( file_exists($file) )
			{
				if ( @unlink($file) )
				{
					self::_addMessage('Language cache <b>'.htmlspecialchars($file).'</b> deleted.');
				}
				else
				{
					self::_addError('ERROR: Could not delete language cache <b>'.htmlspecialchars($file).'<b>.');
				}
			}
		}
	}

	public static function messageAppend(&$moduleObj, &$log)
	{
		$lastMessage = array_pop($log->mMessages);

		foreach ( self::$messages as $message )
		{
			if ( $message['type'] == 'error' )
			{
				$log->addError(strip_tags($message['content']));
			}
			else
			{
				$log->add(strip_tags($message['content']));
			}
		}

		$log->mMessages[] = $lastMessage;
	}
}

?>
